package org.tim.file.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.tim.file.common.FileResultBean;
import org.tim.file.common.UploadItem;
import ws.schild.jave.Encoder;
import ws.schild.jave.EncoderException;
import ws.schild.jave.InputFormatException;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.encode.AudioAttributes;
import ws.schild.jave.encode.EncodingAttributes;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author admin
 */
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping("/upload")
public class InfraFileController {
    private final FileStorageService fileStorageService;
    //上传的文件类型
   String[] imageFilter = {"gif","jpg","jpeg","bmp","png"};
   String[] videoFilter={"mp4","flv","wmv"};
   String[] audioFilter={"acc","amr","mp3","wav"};


    @RequestMapping(value = "/UploadifyAvatarServlet", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public   HashMap<String,Object>  UploadifyAvatarServlet(@RequestParam MultipartFile file,String userId) {
        HashMap<String,Object> result = new HashMap<>();

        String checksum = System.currentTimeMillis()+"";
        try {
            checksum = SecureUtil.md5().digestHex(file.getBytes());
            log.info("MultipartFile Md5: {}", checksum);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        String fileTypeName = getFileExtension(file.getOriginalFilename());
        String path = "avatar/o/";
        String fileName = userId+"."+fileTypeName;
        FileInfo fileInfo = this.fileStorageService.of(file)
                .setHashCalculatorMd5()
                .setPath(path)
                .setSaveFilename(fileName)
                .upload();

        log.info("FileInfo Md5: {}", fileInfo.getHashInfo().getMd5());
        result.put("oUrl",fileInfo.getUrl());
        result.put("path",fileInfo.getOriginalFilename());
        result.put("resultCode",1);
        return  result;
    }




    @RequestMapping(value = "/UploadifyServlet", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public   HashMap<String,String>  upload(@RequestParam MultipartFile file) {
        HashMap<String,String> result = new HashMap<>();
        String date = DateUtil.format(LocalDateTime.now(), "yyyy/MM/dd")+"/";
        String checksum = System.currentTimeMillis()+"";
        try {
             checksum = SecureUtil.md5().digestHex(file.getBytes());
            log.info("MultipartFile Md5: {}", checksum);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        FileInfo fileInfo = this.fileStorageService.of(file)
                .setHashCalculatorMd5()
                .setPath(date)
                .upload();

        log.info("FileInfo Md5: {}", fileInfo.getHashInfo().getMd5());
        result.put("url",fileInfo.getUrl());
        result.put("path",fileInfo.getOriginalFilename());
        return  result;
    }


    @RequestMapping(value = "/UploadServlet", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public   HashMap<String,Object>  UploadServlet(MultipartHttpServletRequest request) {
        HashMap<String,Object> result = new HashMap<>();
        String date = DateUtil.format(LocalDateTime.now(), "yyyy/MM/dd")+"/";
        String checksum = System.currentTimeMillis()+"";
        // 将数组转换为 List
        List<String> imageFilterList = Arrays.asList(imageFilter);
        List<String> videoFilterList = Arrays.asList(videoFilter);
        List<String> audioFilterList = Arrays.asList(audioFilter);

        List<UploadItem> images = new ArrayList<>();
        List<UploadItem> audios = new ArrayList<>();
        List<UploadItem> videos = new ArrayList<>();
        List<UploadItem> others = new ArrayList<>();

        Map<String, MultipartFile> fileMap = request.getFileMap();
        for (Map.Entry<String, MultipartFile> entry : fileMap.entrySet()) {
            MultipartFile file = entry.getValue();
            String originalFilename =  file.getOriginalFilename();
            String fileTypeName = getFileExtension(originalFilename);


            if (!file.isEmpty()) {
                // 处理文件
                try {
                    checksum = SecureUtil.md5().digestHex(file.getBytes());
                    log.info("MultipartFile Md5: {}", checksum);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                FileInfo fileInfo = null;
                if (audioFilterList.contains(fileTypeName)){
                    //音频转化后在保存
                    if (fileTypeName.equals("amr")){

                       File target = FileUtil.createTempFile(".mp3",true);
                       //amr转mp3
                        amrToMp3(file,target);
                        fileInfo = this.fileStorageService.of(target)
                                .setHashCalculatorMd5()
                                .setPath(date)
                                .upload();
                    }

                }else {
                     fileInfo = this.fileStorageService.of(file)
                            .setHashCalculatorMd5()
                            .setPath(date)
                            .upload();
                }

                String url = fileInfo.getUrl();
                if (imageFilterList.contains(fileTypeName)){
                    //图片
                    UploadItem uploadItem = new UploadItem(originalFilename,url,url);
                    images.add(uploadItem);
                }
                else  if (videoFilterList.contains(fileTypeName)){
                    //视频
                    UploadItem uploadItem = new UploadItem(originalFilename,url,url);
                    videos.add(uploadItem);
                }
                else  if (audioFilterList.contains(fileTypeName)){
                    //音频  转化为
                    UploadItem uploadItem = new UploadItem(originalFilename,url,url);
                    audios.add(uploadItem);
                }else {
                    UploadItem uploadItem = new UploadItem(originalFilename,url,url);
                    others.add(uploadItem);
                }

            }
        }

        FileResultBean fileResultBean = new FileResultBean();
        fileResultBean.setAudios(audios);
        fileResultBean.setImages(images);
        fileResultBean.setVideos(videos);
        fileResultBean.setOthers(others);

        result.put("data", JSONUtil.parseObj(fileResultBean));
        result.put("total",fileMap.size()+"");
        result.put("resultCode",1);
        result.put("success",fileMap.size()+"");
        result.put("failure",0);

        return  result;
    }

    private void amrToMp3(MultipartFile file,File target){

        try {

            InputStream inputStream = file.getInputStream();
            File source = FileUtil.createTempFile();
            FileUtil.writeFromStream(inputStream,source);
            // 设置音频属性
            AudioAttributes audio = new AudioAttributes();
            audio.setCodec("libmp3lame"); // 使用LAME MP3编码器
            audio.setBitRate(128000);     // 设置比特率
            audio.setChannels(2);         // 设置声道数
            audio.setSamplingRate(44100); // 设置采样率

            // 设置编码属性
            EncodingAttributes attrs = new EncodingAttributes();
            attrs.setOutputFormat("mp3"); // 输出格式为MP3
            attrs.setAudioAttributes(audio);

            // 创建编码器并执行转换
            Encoder encoder = new Encoder();
            encoder.encode(new MultimediaObject(source), target, attrs);
            if (source.exists()){
                source.delete();
            }
            System.out.println("转换成功！");
        } catch (EncoderException | IOException e) {
            e.printStackTrace();
        }

    }



    @RequestMapping(value = "/UploadVoiceServlet", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public   HashMap<String,String>  UploadVoiceServlet(@RequestParam MultipartFile file) {
        HashMap<String,String> result = new HashMap<>();
        String date = DateUtil.format(LocalDateTime.now(), "yyyy/MM/dd")+"/";
        String checksum = System.currentTimeMillis()+"";


        try {
             checksum = SecureUtil.md5().digestHex(file.getBytes());
            log.info("MultipartFile Md5: {}", checksum);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        FileInfo fileInfo = this.fileStorageService.of(file)
                .setHashCalculatorMd5()
                .setSaveFilename(checksum+".wav")
                .setPath(date)
                .upload();

        log.info("FileInfo Md5: {}", fileInfo.getHashInfo().getMd5());
        result.put("url",fileInfo.getUrl());
        result.put("path",fileInfo.getOriginalFilename());
        return  result;
    }

    public  String getFileExtension(String fileName) {
        if (fileName == null || fileName.isEmpty()) {
            return "";
        }

        int dotIndex = fileName.lastIndexOf('.');
        if (dotIndex == -1) {
            return ""; // 没有扩展名
        }

        return fileName.substring(dotIndex + 1);
    }







}
